package cn.tedu.charging.order.rabbitmq;


import cn.tedu.charging.order.config.RabbitMQConfiguration;
import cn.tedu.charging.order.dao.repository.OrderRepository;
import cn.tedu.charging.order.pojo.po.ChargingOrderFailPO;
import cn.tedu.charging.order.pojo.po.ChargingOrderSuccessPO;
import cn.tedu.charging.order.quartz.SpringContextUtils;
import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * RabbitMQ的消费者
 */
@Component
public class RabbitMQConsumer {


    private static final Logger log = LoggerFactory.getLogger(RabbitMQConsumer.class);

    @Autowired
    private OrderRepository orderRepository;

    /**
     * Spring封装的 消费者方法 basicConsume
     * channel.basicConsume(queue,true,
     *                 (consumerTag,message) ->
     *                         System.out.println("message:"+ new String(message.getBody()))
     *                 ,(consumerTag,message)->{});
     * @param message
     */

    /**
     * 死信队列的消费者 消费的是死信队列 实现延迟消息
     * 7. 判断是否有订单记录
     * 8. 有成功订单记录  订单状态是 充电中 说明设备 有响应，设备收到了指令后，正常的返回开始充电成功的响应，保存成功订单记录  设备有响应-开始充电 无需处理
     * 9. 没有成功订单记录
     * 10. 判断是否有失败订单记录
     * 11. 有失败订单记录  失败原因 设备有响应-无法充电  无需处理
     * 12. 没有失败订单记录
     * 13. 插入失败订单记录 失败原因 设备无响应 通知用户和维修人员 设置枪状态为 故障
     *
     * @param message
     */
    @RabbitListener(queues = RabbitMQConfiguration.DEAD_LETTER_QUEUE_NAME)
    public void receive(String orderNo,Message message, Channel channel) {
        /*OrderSuccessMapper orderSuccessMapper =
                SpringContextUtils.getBean(OrderSuccessMapper.class);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("bill_id", orderNo);
        ChargingOrderSuccessPO chargingOrderSuccessPO =
                orderSuccessMapper.selectOne(queryWrapper);*/

        //OrderRepository orderRepository = SpringContextUtils.getBean(OrderRepository.class);
        log.debug("查询成功订单记录:订单号:{}",orderNo);
        ChargingOrderSuccessPO orderSuccessPO =
                orderRepository.getSuccessOrderByOrderNo(orderNo);
        log.debug("查询成功订单记录:订单号:{},查询结果{}",orderNo,orderSuccessPO);
        //判断是否有订单记录
        if (orderSuccessPO == null){
            //没有成功订单记录
            log.debug("查询失败订单记录:订单号:{}",orderNo);
            ChargingOrderFailPO orderFailPO =
                    orderRepository.getFailOrderByOrderNo(orderNo);
            log.debug("查询失败订单记录:订单号:{},查询结果{}",orderNo,orderFailPO);
            //判断是否有失败订单记录
            if (orderFailPO == null) {
                log.debug("没有失败订单记录,说明设备<<设备无响应>>,插入失败订单记录");
                ChargingOrderFailPO chargingOrderFailPO = new ChargingOrderFailPO();
                chargingOrderFailPO.setBillId(orderNo);
                chargingOrderFailPO.setFailDesc("设备无响应");
                int row = orderRepository.insertFailOrder(chargingOrderFailPO);
                log.debug("插入失败订单记录:{},影响行数:{}",chargingOrderFailPO,row);
                log.debug("<<通知充电用户>> 更换设备");
                log.debug("<<通知充电用户>> 给用户发短信，表示歉意");
                log.debug("<<通知充电用户>> 给用户发短信，发送优惠券 营销系统，给用户心灵上的安慰");
                log.debug("<<通知设备管理员>> 对设备进行检修");
                log.debug("<<修改枪的状态为 维护中>>");
            }else {
                log.debug("有失败订单记录,说明设备<<设备有响应-无法充电>>,无需处理");
            }
        }else {
            log.debug("有成功订单记录,说明设备<<设备有响应-开始充电>>,无需处理");
        }
        //代码执行到这里，说明业务处理完成，收到ack告诉mq，消息已经成功处理了，mq可以把消息删除
        try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),
                    false);
        } catch (Exception e) {
            log.error("消费到延迟消息-异常:{}",e);
        }
    }
}
